package cn.com.surker.sale.util;

import cn.com.surker.enums.sale.CalcAdjustTypeEnum;
import cn.com.surker.enums.sale.ContractSubsidyTypeEnum;
import cn.com.surker.enums.sale.SubsidyCountTypeEnum;
import cn.com.surker.util.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author lucky
 * @create 2024年08月12 14:40
 * @desc 信息加计算公式
 */
public class PriceInfoUtil {

    public static void main(String[] args){
        Double d = calcJCBH(400.0,80.0,0);
        Double d1 = calcGDJC(400.0,320.0,410.0,0);
        Double d2 = calcXF(400.0,15.0,0);
        Double d3 = calcJC(440.0,290.0, 410.0, 3.0,0,0);
        Double d4 = calcJC(410.0,290.0, 440.0, 3.0,0,0);
        Double d5 = calcJCJE(400.0, 300.0, 382.0, 10.0, 0);
        Double d6 = calcJCJE(400.0, 300.0, 421.0, 10.0, 0);
        System.out.println(d);
        System.out.println(d1);
        System.out.println(d2);
        System.out.println(d3);
        System.out.println(d4);
        System.out.println(d5);
        System.out.println(d6);
        Map<String, Object> map = convertSubsidyLabel();
        for (String key : map.keySet()) {
            System.out.println(key + "\t" + map.get(key));
        }
    }

    /**
     * 转换单价单位描述
     * @return
     */
    public static Map<String, Object> convertSubsidyLabel() {
        Map<String, Object> map = new HashMap<>();
        for (int i = 0; i < ContractSubsidyTypeEnum.values().length; i++) {
            Integer type = ContractSubsidyTypeEnum.values()[i].getCode();
            for (int j = 0; j < SubsidyCountTypeEnum.values().length; j++) {
                Integer countType = SubsidyCountTypeEnum.values()[j].getCode();
                String key = ContractSubsidyTypeEnum.values()[i].getCode() + "_" + SubsidyCountTypeEnum.values()[j].getCode();
                String tip = "";
                switch (type){
                    case 0://泵送方量
                    case 1://运输方量
                    case 5://砂浆
                    case 6://水
                    case 7://其他
                        switch (countType) {
                            case 0://按补差方量计算
                                tip = "不足保底补差每方补助/元;(例:泵送、运输保底60方,实际泵送、运输50方,则[60-50] * 保底单价 = 补贴金额)";
                                break;
                            case 1://按批次计算
                                tip = "不足保底每批次补助/元;(例:单批次(合并任务单算一次)泵送、运输保底60方,实际泵送、运输50方,则 计算次数 * 保底单价 = 补贴金额)";
                                break;
                            case 2://按车次计算
                                tip = "不足保底每车次补助/元;(例:泵送、运输保底60方,实际泵送、运输50方,共5车次,则 5(车次) * 保底单价 = 补贴金额)";
                                break;
                            case 3://按泵送方量计算
                                tip = "不足保底泵送每方补助/元;(例:泵送保底60方,实际泵送50方,则 50(实际泵送量) * 保底单价 = 补贴金额)";
                                break;
                            case 4://按运输方量计算
                                tip = "不足保底运输每方补助/元;(例:运输保底80方,实际运输65方,则 65(实际运输量) * 保底单价 = 补贴金额)";
                                break;
                        }
                        break;
                    case 2://超时浇筑
                    case 3://润管剂、润泵剂
                    case 4://接管补助
                        tip = "不足保底单次补助/元;(例:浇筑超时、润管剂、润泵剂使用、接管补助,则 计算次数 * 保底单价 = 补贴金额;暂不支持超时按小时计算)";
                        break;
                    case 9://运距补助
                        switch (countType) {
                            case 0://按补差方量计算
                                tip = "不足运距,补差每公里补助/元;(例:保底运输距离30km,实际运输距离22方,则[30-22] * 保底单价 = 补贴金额)";
                                break;
                            case 1://按批次计算
                                tip = "不足运距,每批次补助/元;(例:保底运输距离30km,实际运输距离22方,则[30-22] * 保底单价 = 补贴金额)";
                                break;
                            case 2://按车次计算
                                tip = "不足运距,每车次补助/元;(例:保底运输距离30km,实际运输距离22方,共运输8车次,则 8(车次) * 保底单价 = 补贴金额)";
                                break;
                            case 3://按泵送方量计算
                                tip = "不足运距,泵送每公里补助/元;(例:保底运输距离30km,实际运输距离22方,则 22(实际运距) * 保底单价 = 补贴金额)";
                                break;
                            case 4://按运输方量计算
                                tip = "不足运距,发货方量每公里补助/元;(例:保底运输距离30km,实际运输距离22方,则 22(实际运距) * 保底单价 = 补贴金额)";
                                break;
                        }
                }
                map.put(key, tip);
            }
        }
        return map;
    }

    /**
     * 按基础标号调整
     * @param basicPrice
     * @param adjustPrice
     * @return
     */
    public static Double calcJCBH(Double basicPrice, Double adjustPrice, Integer roundType) {
        if (StringUtils.isAllParamNull(basicPrice, adjustPrice))
            return 0.0;
        if (adjustPrice > 0)
            return StringUtils.subtractDouble(basicPrice, adjustPrice);
        else
            return StringUtils.addDouble(basicPrice, adjustPrice);
    }

    /**
     * 按指定标号调整固定价差,其他标号按级差调整(元)
     * @param basicContractPrice 指定标号合同价
     * @param adjustContractPrice 生成标号合同价
     * @param infoPrice 指定标号信息价
     * @param adjustPrice 调整金额
     * @param roundType
     * @return
     */
    public static Double calcZDJCBH(Double basicContractPrice, Double adjustContractPrice, Double infoPrice, Double adjustPrice, Integer roundType) {
        if (StringUtils.isAllParamNull(basicContractPrice,adjustContractPrice, adjustPrice, infoPrice))
            return 0.0;

        return StringUtils.formatDouble(adjustContractPrice - basicContractPrice + infoPrice - adjustPrice, roundType);
    }
    public static Double calcZDGDHTJC(Double basicContractPrice, Double adjustContractPrice, Double adjustPrice, Integer roundType) {
        if (StringUtils.isAllParamNull(basicContractPrice,adjustContractPrice, adjustPrice))
            return 0.0;
        return StringUtils.formatDouble(basicContractPrice + (adjustContractPrice - basicContractPrice) - adjustPrice, roundType);
    }
    /**
     * 固定价差  执行价= 合同价  + 比对价 - 基准价
     * @param basicPrice 基准价
     * @param contractPrice 合同价
     * @param contrastPrice 比对价
     * @return
     */
    public static Double calcGDJC(Double basicPrice, Double contractPrice, Double contrastPrice, Integer roundType) {
        if (StringUtils.isAllParamNull(basicPrice, contractPrice, contrastPrice))
            return 0.0;
//        Double result = StringUtils.subtractDouble(StringUtils.addDouble(contractPrice , basicPrice) ,contractPrice);
        Double result = StringUtils.formatDouble(contractPrice + contrastPrice - basicPrice, 3);
        return result;
    }

    /**
     *
     * @param basicPrice 基准价
     * @param adjustRate 浮动率
     * @return
     */
    public static Double calcXF(Double basicPrice, Double adjustRate, Integer roundType) {
        if (StringUtils.isAllParamNull(basicPrice, adjustRate))
            return 0.0;
//        taxRate = (100 + taxRate) / 100;//税率
        adjustRate = StringUtils.divide(adjustRate , 100.0).doubleValue();//税率
//        basicPrice = basicPrice * (1.0 - adjustRate);
        basicPrice = StringUtils.multiply(basicPrice, 1.0 - adjustRate).doubleValue();
//        basicPrice = basicPrice - adjustPrice;
//        basicPrice = StringUtils.multiplyDouble(basicPrice , 1.0);
        return basicPrice;
    }

    /**
     * 按指定标号信息价浮动率调整(%),其他标号按合同价级差调整
     * 计算标号价格 + (调整标号合同价 - 指定标号合同价)
     * @param basicContractPrice
     * @param adjustContractPrice
     * @param basicPrice
     * @param adjustRate
     * @param roundType
     * @return
     */
    public static Double calcZDHTXF(Double basicContractPrice, Double adjustContractPrice,Double basicPrice,
                                    Double adjustRate, Integer roundType) {
        if (StringUtils.isAllParamNull(basicPrice, adjustRate))
            return 0.0;
//        taxRate = (100 + taxRate) / 100;//税率
        adjustRate = StringUtils.divide(adjustRate , 100.0).doubleValue();//税率
//        basicPrice = basicPrice * (1.0 - adjustRate);
        Double tempBasicPrice = StringUtils.multiply(basicPrice, 1.0 - adjustRate).doubleValue();
        tempBasicPrice = StringUtils.addDouble(tempBasicPrice, StringUtils.subtractDouble(adjustContractPrice, basicContractPrice));
//        basicPrice = basicPrice - adjustPrice;
//        basicPrice = StringUtils.multiplyDouble(basicPrice , 1.0);
        return tempBasicPrice;
    }
    /**
     * 固定价差  执行价= 合同价  - (比对价 + 调整价 - 基准价)
     * @param basicPrice 基准价
     * @param contractPrice 合同价
     * @param contrastPrice 比对价
     * @return
     */
    public static Double calcZDGDJC(Double basicPrice, Double contractPrice, Double contrastPrice,Double adjustPrice, Integer roundType) {
        if (StringUtils.isAllParamNull(basicPrice, contractPrice, contrastPrice))
            return 0.0;
        Double result = StringUtils.subtractDouble(StringUtils.addDouble(contrastPrice, adjustPrice), basicPrice);
        result = StringUtils.subtractDouble(contractPrice, result);
        return result;
    }
    /**
     * 价差对比率
     * @param basicPrice 基准价
     * @param contractPrice 合同价
     * @param contrastPrice 对比价
     * @param contrastRate 对比率
     * @param calcAdjustType 调整价格类型
     * @return
     */
    public static Double calcJC(Double basicPrice, Double contractPrice, Double contrastPrice, Double contrastRate, Integer calcAdjustType, Integer roundType) {
        if (StringUtils.isAllParamNull(basicPrice, contractPrice, contrastPrice, contrastRate))
            return 0.0;
        if (StringUtils.isNull(calcAdjustType))
            calcAdjustType = CalcAdjustTypeEnum.JZ.getCode();
        Double basicAdjustPrice = basicPrice;//调整价格类型
        if (calcAdjustType == CalcAdjustTypeEnum.HT.getCode())
            basicAdjustPrice = contractPrice;
        else if (calcAdjustType == CalcAdjustTypeEnum.HT.getCode())
            basicAdjustPrice = contrastPrice;

        if (calcAdjustType == CalcAdjustTypeEnum.JZ.getCode()) {
            Double zContrastRate = StringUtils.formatDouble(StringUtils.divide(contrastRate, 100.0).doubleValue(), 2);
            Double fContrastRate = 0 - zContrastRate;//负对比率
            Double conPrice_ = basicPrice - contrastPrice;
            Double d1 = Math.abs(conPrice_);
            Double rate = d1 / basicPrice;
            if (conPrice_ < 0)
                rate = 0 -rate;
            if (rate > 0 && rate > zContrastRate) {
                Double adjustPrice = (rate - zContrastRate) * basicAdjustPrice;
                contractPrice = StringUtils.addDouble(contractPrice, adjustPrice);
            } else if (rate < 0 && rate < fContrastRate){
                Double adjustPrice = (rate - fContrastRate) * basicAdjustPrice;
                contractPrice = StringUtils.addDouble(contractPrice, adjustPrice);
            }
        } else {
            if (basicPrice > contrastPrice) {
//                Double tempContrastRate = basicPrice / contrastPrice;
//                tempContrastRate = tempContrastRate - (100 + contrastRate) / 100;
                Double adjustPrice = basicAdjustPrice * (basicPrice / contrastPrice - (100 + contrastRate) / 100);
                contractPrice = StringUtils.addDouble(contractPrice, adjustPrice);
            } else if (basicPrice < contrastPrice) {
                Double  tt = (100 - contrastRate) / 100 - basicPrice / contrastPrice;
                Double adjustPrice = basicAdjustPrice * ((100 - contrastRate) / 100 - basicPrice / contrastPrice);
                contractPrice = StringUtils.subtractDouble(contractPrice, adjustPrice);
            }
        }

        return contractPrice;
    }

    /**
     * 价差对金额
     * @param basicPrice 基准价
     * @param contractPrice 合同价
     * @param contrastPrice 对比价
     * @param money 对比金额
     * @return
     */
    public static Double calcJCJE(Double basicPrice, Double contractPrice, Double contrastPrice, Double money, Integer roundType) {
        if (StringUtils.isAllParamNull(basicPrice, contractPrice, contrastPrice, money))
            return 0.0;
//        if (StringUtils.isNull(calcAdjustType))
//            calcAdjustType = CalcAdjustTypeEnum.JZ.getCode();
//        Double basicAdjustPrice = basicPrice;//调整价格类型
//        if (calcAdjustType == CalcAdjustTypeEnum.HT.getCode())
//            basicAdjustPrice = contractPrice;
//        else if (calcAdjustType == CalcAdjustTypeEnum.HT.getCode())
//            basicAdjustPrice = contrastPrice;
        Double fMoney = 0 - money;//负对金额
        Double conPrice_ = basicPrice - contrastPrice;
        Double d1 = Math.abs(conPrice_);
        if (conPrice_ > 0 && conPrice_ > money) {
            Double adjustPrice = (conPrice_ - money);
            contractPrice = StringUtils.addDouble(contractPrice, adjustPrice);
        } else if (conPrice_ < 0 && conPrice_ < fMoney){
            Double adjustPrice = (conPrice_ - fMoney);
            contractPrice = StringUtils.addDouble(contractPrice, adjustPrice);
        }
        return contractPrice;
    }
}
